import time
import subprocess
import redis

client = redis.Redis('', 6379)
parallelism = int(client.get('parallelism'))
strategies = ('hash', 'module', 'leastKey', 'leastCount')

def stat():
    subprocess.getoutput('./util.sh stat')

def calc(parallelism=parallelism, file='info/count_res'):
    output = subprocess.getoutput('./util.sh calc ' + str(parallelism) + ' ' + file)
    output = output.splitlines()
    ratio = output[0].split(' ')[2]
    count = output[1].split(' ')[0]
    return (float(ratio), int(count))

def select():
    current = client.get('keyByType')
    if (current == None):
        current = 0
    else:
        current = int(current)
    print(current, strategies[current])
    max = 0.0
    maxi = -1
    for i in range(len(strategies)):
        r = calc(file='info/' + strategies[i] + '_res')[0]
        print(strategies[i], r)
        if (r > max):
            max = r
            maxi = i
    print(maxi, strategies[maxi], max)
    if (maxi != current):
        client.set('keyByType', maxi)
        client.publish('keyByChannel', 'type@' + str(maxi))
        print('switch from ' + strategies[current] + ' to ' + strategies[maxi])

class TimeTrigger:
    last = 0
    interval = 0

    def __init__(self, interval):
        self.last = time.time()
        self.interval = interval

    def trigger(self) -> bool:
        now = time.time()
        if (now - self.last >= self.interval):
            self.last = now
            return True
        else:
            return False

class CountTrigger:
    last = 0
    interval = 0

    def __init__(self, interval):
        stat()
        self.last = calc()[1]
        self.interval = interval

    def trigger(self) -> bool:
        now = calc()[1]
        if (now - self.last >= self.interval):
            self.last = now
            return True
        else:
            return False

class ThresholdTrigger:
    threshold = 0.0

    def __init__(self, threshold):
        self.threshold = threshold

    def trigger(self) -> bool:
        current = client.get('keyByType')
        if (current == None):
            current = 0
        else:
            current = int(current)
        r = calc(file='info/' + strategies[current] + '_res')[0]
        return r < self.threshold

interval = 60
trigger = ThresholdTrigger(0.8)
while (True):
    stat()
    if (trigger.trigger()):
        select()
        subprocess.getoutput('python3 aging.py')
    time.sleep(interval)
